﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Components.Analytics.SchemaSvc;
using Liquid;

namespace Components.Analytics
{
    [EditorComponentType(ComponentType = typeof(DocumentClusteringComponent))]
    public partial class DocumentClusteringEditor : ComponentEditorBase
    {
        private bool initialized = false;
        private string DefaultDbServer = "localhost";
        private string DefaultUserName = "sa";
        private string DefaultPassword = "xiaodong";

        public DocumentClusteringEditor()
        {
            InitializeComponent();
            this.txtDbServer.Text = this.DefaultDbServer;
            initialized = true;
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.SaveSettings();
            if (this.ComponentUpdated != null)
                this.ComponentUpdated(this._Node, this._ClusterComponent);
            this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        #region Overrides of ComponentEditorBase
        private object _Node;
        private DocumentClusteringComponent _ClusterComponent;
        public override event OnComponentUpdated ComponentUpdated;
        public override void LoadSettings(object node, WorkflowComponentBase component)
        {
            this._Node = node;
            this._ClusterComponent = (DocumentClusteringComponent) component;

            DocumentClusteringInstruction instruction =
                (DocumentClusteringInstruction) this._ClusterComponent.Instruction;

            this.txtTaskName.Text = instruction.TaskName;

            Regex svrRegex=new Regex("Server\\s*=\\s*([^\\s;]+)",RegexOptions.IgnoreCase);
            Match svrMatch = svrRegex.Match(instruction.ConnStr);
            if (svrMatch.Success)
            {
                this.txtDbServer.Text = svrMatch.Groups[1].Value;
            }
            Regex dbRegex = new Regex("Database\\s*=\\s*([^\\s;]+)", RegexOptions.IgnoreCase);
            Match dbMatch = dbRegex.Match(instruction.ConnStr);
            if (dbMatch.Success)
            {
                this.txtProjDB.Text = dbMatch.Groups[1].Value;
            }
            
            this.txtSQL.Load(Format.Text,instruction.SQL);
            this.btnParseSQL_Click(this,null);
            this.cboProjIDFieldInSQL.SelectedItem = instruction.DocIDFieldFromSQL;
            this.cboProjTitleFieldInSQL.SelectedItem = instruction.DocTitleFieldFromSQL;

            this.txtTermDB.Text = instruction.TermDB;
            this.btnPopulateTermDBTables_Click(this, null);
            this.cboTermTable.SelectedItem = instruction.TermTable;
            this.cboMappingTable.SelectedItem = instruction.MappingTable;
            this.cboTermIDFieldInTermTable.SelectedItem = instruction.TermIDFieldInTermTable;
            this.cboPhraseFieldInTermTable.SelectedItem = instruction.PhraseFieldInTermTable;
            this.cboTermIDFieldInMappingTable.SelectedItem = instruction.TermIDFieldInMappingTable;
            this.cboProjIDFieldInMappingTable.SelectedItem = instruction.DocIDFieldInMappingTable;
            this.cboTermFreqFieldInMappingTable.SelectedItem = instruction.TermFreqFieldInMappingTable;

            this.txtResultDB.Text = instruction.OutputDB;
            this.btnGetResultDBTables_Click(this,null);
            this.cboResultTable.SelectedItem = instruction.ResultTable;
            this.cboTaskField.SelectedItem = instruction.TaskNameField;
            this.cboOutputField.SelectedItem = instruction.DataField;
        }

        public override void SaveSettings()
        {
            DocumentClusteringInstruction instruction =
                (DocumentClusteringInstruction)this._ClusterComponent.Instruction;

            instruction.TaskName = this.txtTaskName.Text;
            instruction.ConnStr = string.Format("Server={0};Database={1};User ID={2};Password={3}",
                                                this.txtDbServer.Text, this.txtProjDB.Text,
                                                this.DefaultUserName, this.DefaultPassword);
            instruction.SQL = this.txtSQL.Save(Format.Text,RichTextSaveOptions.None);
            instruction.DocIDFieldFromSQL = this.cboProjIDFieldInSQL.SelectedIndex >= 0
                                                ? this.cboProjIDFieldInSQL.SelectedItem.ToString()
                                                : "";
            instruction.DocTitleFieldFromSQL = this.cboProjTitleFieldInSQL.SelectedIndex >= 0
                                                   ? this.cboProjTitleFieldInSQL.SelectedItem.ToString()
                                                   : string.Empty;

            instruction.TermDB = this.txtTermDB.Text;
            instruction.TermTable = this.cboTermTable.SelectedIndex >= 0
                                        ? this.cboTermTable.SelectedItem.ToString()
                                        : string.Empty;
            instruction.TermIDFieldInTermTable = this.cboTermIDFieldInTermTable.SelectedIndex >= 0
                                                     ? this.cboTermIDFieldInTermTable.SelectedItem.ToString()
                                                     : string.Empty;
            instruction.PhraseFieldInTermTable = this.cboPhraseFieldInTermTable.SelectedIndex >= 0
                                                     ? this.cboPhraseFieldInTermTable.SelectedItem.ToString()
                                                     : string.Empty;

            instruction.MappingTable = this.cboMappingTable.SelectedIndex >= 0
                                           ? this.cboMappingTable.SelectedItem.ToString()
                                           : string.Empty;
            instruction.TermIDFieldInMappingTable = this.cboTermIDFieldInMappingTable.SelectedIndex >= 0
                                                        ? this.cboTermIDFieldInMappingTable.SelectedItem.ToString()
                                                        : string.Empty;
            instruction.DocIDFieldInMappingTable = this.cboProjIDFieldInMappingTable.SelectedIndex >= 0
                                                       ? this.cboProjIDFieldInMappingTable.SelectedItem.ToString()
                                                       : string.Empty;
            instruction.TermFreqFieldInMappingTable = this.cboTermFreqFieldInMappingTable.SelectedIndex >= 0
                                                          ? this.cboTermFreqFieldInMappingTable.SelectedItem.ToString()
                                                          : string.Empty;

            instruction.OutputDB = this.txtResultDB.Text;
            instruction.ResultTable = this.cboResultTable.SelectedIndex >= 0
                                          ? this.cboResultTable.SelectedItem.ToString()
                                          : string.Empty;
            instruction.TaskNameField = this.cboTaskField.SelectedIndex >= 0
                                            ? this.cboTaskField.SelectedItem.ToString()
                                            : string.Empty;
            instruction.DataField = this.cboOutputField.SelectedIndex >= 0
                                        ? this.cboOutputField.SelectedItem.ToString()
                                        : string.Empty;
        }

        #endregion

        private void btnParseSQL_Click(object sender, RoutedEventArgs e)
        {
            string sql = this.txtSQL.Save(Format.Text, RichTextSaveOptions.None);
            if(string.IsNullOrEmpty(sql))
            {
                DocumentClusteringInstruction instruction =
                    (DocumentClusteringInstruction) this._ClusterComponent.Instruction;
                if(!string.IsNullOrEmpty(instruction.SQL))
                    sql = instruction.SQL;
            }
            if(!string.IsNullOrEmpty(this.txtDbServer.Text) && 
                !string.IsNullOrEmpty(this.txtProjDB.Text) &&
                !string.IsNullOrEmpty(sql))
            {
                SchemaServiceClient client=new SchemaServiceClient();
                client.ListTableColumnNamesUsingSQL2Completed+=new EventHandler<ListTableColumnNamesUsingSQL2CompletedEventArgs>(client_ListTableColumnNamesUsingSQL2Completed);
                client.ListTableColumnNamesUsingSQL2Async(
                    this.txtDbServer.Text,
                    this.txtProjDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword,
                    sql);
            }
        }

        void client_ListTableColumnNamesUsingSQL2Completed(object sender, ListTableColumnNamesUsingSQL2CompletedEventArgs e)
        {
            this.cboProjIDFieldInSQL.Items.Clear();
            this.cboProjTitleFieldInSQL.Items.Clear();
            foreach(string colName in e.Result)
            {
                this.cboProjIDFieldInSQL.Items.Add(colName);
                this.cboProjTitleFieldInSQL.Items.Add(colName);
            }
            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction) this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboProjIDFieldInSQL, instruction.DocIDFieldFromSQL);
            this.SelectComboxItem(this.cboProjTitleFieldInSQL, instruction.DocTitleFieldFromSQL);
        }

        private void btnPopulateTermDBTables_Click(object sender, RoutedEventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txtDbServer.Text) && 
                !string.IsNullOrEmpty(this.txtTermDB.Text))
            {
                SchemaServiceClient client = new SchemaServiceClient();
                client.ListTables2Completed += new EventHandler<ListTables2CompletedEventArgs>(client_ListTables2Completed);
                client.ListTables2Async(this.txtDbServer.Text, this.txtTermDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword, 
                    "dbo");
            }
        }

        void client_ListTables2Completed(object sender, ListTables2CompletedEventArgs e)
        {
            this.cboTermTable.Items.Clear();
            this.cboMappingTable.Items.Clear();
            foreach(string tblName in e.Result)
            {
                this.cboTermTable.Items.Add(tblName);
                this.cboMappingTable.Items.Add(tblName);
            }

            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction)this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboTermTable, instruction.TermTable);
            this.SelectComboxItem(this.cboMappingTable, instruction.MappingTable);
        }

        private void cboTermTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(!initialized)
                return;

            if(!string.IsNullOrEmpty(this.txtDbServer.Text) && 
                !string.IsNullOrEmpty(this.txtTermDB.Text) && 
                this.cboTermTable.SelectedIndex>=0)
            {
                SchemaServiceClient client = new SchemaServiceClient();
                client.ListTableColumnNames2Completed += new EventHandler<ListTableColumnNames2CompletedEventArgs>(client_ListTableColumnNames2Completed);
                client.ListTableColumnNames2Async(
                    this.txtDbServer.Text,
                    this.txtTermDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword,
                    "dbo",
                    this.cboTermTable.SelectedItem.ToString());
            }
        }

        void client_ListTableColumnNames2Completed(object sender, ListTableColumnNames2CompletedEventArgs e)
        {
            this.cboTermIDFieldInTermTable.Items.Clear();
            this.cboPhraseFieldInTermTable.Items.Clear();
            foreach(string colName in e.Result)
            {
                this.cboTermIDFieldInTermTable.Items.Add(colName);
                this.cboPhraseFieldInTermTable.Items.Add(colName);
            }

            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction)this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboTermIDFieldInTermTable, instruction.TermIDFieldInTermTable);
            this.SelectComboxItem(this.cboPhraseFieldInTermTable, instruction.PhraseFieldInTermTable);
        }

        private void cboMappingTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!initialized)
                return;
            if (!string.IsNullOrEmpty(this.txtDbServer.Text) &&
                !string.IsNullOrEmpty(this.txtTermDB.Text) && 
                this.cboMappingTable.SelectedIndex>=0)
            {
                SchemaServiceClient client = new SchemaServiceClient();
                client.ListTableColumnNames2Completed += new EventHandler<ListTableColumnNames2CompletedEventArgs>(client_ListTableColumnNames2Completed2);
                client.ListTableColumnNames2Async(
                    this.txtDbServer.Text,
                    this.txtTermDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword,
                    "dbo",
                    this.cboMappingTable.SelectedItem.ToString());
            }
        }

        void client_ListTableColumnNames2Completed2(object sender, ListTableColumnNames2CompletedEventArgs e)
        {
            this.cboTermIDFieldInMappingTable.Items.Clear();
            this.cboProjIDFieldInMappingTable.Items.Clear();
            this.cboTermFreqFieldInMappingTable.Items.Clear();
            foreach (string colName in e.Result)
            {
                this.cboTermIDFieldInMappingTable.Items.Add(colName);
                this.cboProjIDFieldInMappingTable.Items.Add(colName);
                this.cboTermFreqFieldInMappingTable.Items.Add(colName);
            }

            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction)this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboTermIDFieldInMappingTable, instruction.TermIDFieldInMappingTable);
            this.SelectComboxItem(this.cboProjIDFieldInMappingTable, instruction.DocIDFieldInMappingTable);
            this.SelectComboxItem(this.cboTermFreqFieldInMappingTable, instruction.TermFreqFieldInMappingTable);
        }

        private void btnGetResultDBTables_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(this.txtDbServer.Text) &&
                !string.IsNullOrEmpty(this.txtResultDB.Text))
            {
                SchemaServiceClient client = new SchemaServiceClient();
                client.ListTables2Completed += new EventHandler<ListTables2CompletedEventArgs>(client_ListTables2Completed2);
                client.ListTables2Async(this.txtDbServer.Text, this.txtResultDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword, 
                    "dbo");
            }
        }

        void client_ListTables2Completed2(object sender, ListTables2CompletedEventArgs e)
        {
            this.cboResultTable.Items.Clear();
            foreach (string tblName in e.Result)
            {
                this.cboResultTable.Items.Add(tblName);
            }

            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction)this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboResultTable, instruction.ResultTable);
        }

        private void cboResultTable_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!initialized)
                return;
            if (!string.IsNullOrEmpty(this.txtDbServer.Text) &&
                !string.IsNullOrEmpty(this.txtTermDB.Text) &&
                this.cboResultTable.SelectedIndex >= 0)
            {
                SchemaServiceClient client = new SchemaServiceClient();
                client.ListTableColumnNames2Completed += new EventHandler<ListTableColumnNames2CompletedEventArgs>(client_ListTableColumnNames2Completed3);
                client.ListTableColumnNames2Async(
                    this.txtDbServer.Text,
                    this.txtResultDB.Text,
                    this.DefaultUserName,
                    this.DefaultPassword,
                    "dbo",
                    this.cboResultTable.SelectedItem.ToString());
            }
        }

        void client_ListTableColumnNames2Completed3(object sender, ListTableColumnNames2CompletedEventArgs e)
        {
            this.cboTaskField.Items.Clear();
            this.cboOutputField.Items.Clear();
            foreach (string colName in e.Result)
            {
                this.cboTaskField.Items.Add(colName);
                this.cboOutputField.Items.Add(colName);
            }

            DocumentClusteringInstruction instruction = (DocumentClusteringInstruction)this._ClusterComponent.Instruction;
            this.SelectComboxItem(this.cboTaskField, instruction.TaskNameField);
            this.SelectComboxItem(this.cboOutputField, instruction.DataField);
        }

        private void SelectComboxItem(ComboBox comboBox, string value)
        {
            if(comboBox.Items.Count>0 && !string.IsNullOrEmpty(value))
            {
                for(int i=0;i<comboBox.Items.Count;i++)
                {
                    if(comboBox.Items[i].ToString()==value)
                    {
                        comboBox.SelectedIndex = i;
                        break;
                    }
                }
            }
        }
    }
}

